#include "Turn.hpp"
unsigned int Turn::_dimensions = 0;
const Vector* Turn::_position = NULL;

Turn::Turn( unsigned int turn )
{
	_turn = turn;
	_matrix = NULL;
	_shot   = NULL;
	_own_matrix = false;
	_own_shot   = false;
}

Turn::Turn( std::istream& in )
{
	unsigned int dim;
	in >> _turn;
	in >> dim;
	
	if( dim != Turn::_dimensions )
		throw std::logic_error( "turno con dimensiones distintas a la actual" );

	Vector* S = new Vector(dim);
	in >> *S;

	InvertibleMatrix* M = new InvertibleMatrix(dim);
	in >> *M;

	_matrix = M;
	_shot   = S;
	_own_matrix = true;
	_own_shot   = true;
}

Turn::~Turn()
{
	if( _own_matrix )
		delete _matrix;
	if( _own_shot )
		delete _shot;
}

unsigned int Turn::number() const
{
	return _turn;
}

void Turn::setShot( const Vector& shot )
{
	if( _own_shot )
		delete _shot;
	_shot = &shot;
	_own_shot = false;
}

void Turn::setMatrix( const InvertibleMatrix& matrix )
{
	if( _own_matrix )
		delete _matrix;
	_matrix = &matrix;
	_own_matrix = false;
}

const InvertibleMatrix& Turn::getMatrix() const
{
	return *_matrix;
}

const Vector& Turn::getShot() const
{
	return *_shot;
}

void Turn::dimensions( unsigned int dim )
{
	Turn::_dimensions = dim;
}

unsigned int Turn::dimensions()
{
	return Turn::_dimensions;
}

void Turn::position( const Vector& pos )
{
	Turn::_position = &pos;
}

const Vector& Turn::position()
{
	return *Turn::_position;
}

std::ostream& Turn::write( std::ostream& out ) const
{
	Matrix d = (*_matrix) * (*Turn::_position);
	out << _turn << std::endl 
	    << Turn::_dimensions << std::endl;
	for( unsigned int i = 1 ; i <= d.rows() ; i++ )
		out << d(i,1) << " ";
	out << std::endl << *_matrix;
	return out;
}

std::ostream& operator<< ( std::ostream& out, const Turn& t )
{
	return t.write(out);
}

